﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

using OVS.CoreDomain;
using OVS.CoreDomain.Data;
namespace OVS.Data
{
    public class DalCandidate : Dal<ICandidate, Candidate>, IDalCandidate
    {
        private const string SP_GET_CANDIDATE = "usp_GetCandidate";
        private const string SP_INSERT_CANDIDATE = "usp_InsertCandidate";
        private const string SP_UPDATE_CANDIDATE = "usp_UpdateCandidate";
        private const string SP_SEARCH_CANDIDATES = "usp_SearchCandidates";
        private const string SP_SEARCH_CANDIDATES_CONSTITUENCY = "usp_SearchCandidatesByConstituency";
        private const string SP_ADD_VOTE = "usp_AddVote";
        private const string SP_GET_VOTE = "usp_GetVotes";




        private readonly IDalManager _manager;
        private static readonly IDalCandidate _instance = new DalCandidate();

        public static IDalCandidate Instance
        {
            get { return _instance; }
        }

        public DalCandidate()
        {
            _manager = new DalManager();
        }

        public DalCandidate(IDalManager manager)
        {
            _manager = manager;
        }

        protected override void Convert(ICandidate obj, DataRow row)
        {
            obj.CandidateId = _manager.GetValue<int>(row, "CandidateId");
            IWard ward = new Ward();
            ward.WardId = _manager.GetValue<string>(row, "WardId");
            IDistrict district = new District();
            district.DistrictId = _manager.GetValue<string>(row, "DistrictId");

            IPanchayat panchayat = new Panchayat();
            panchayat.PanchayatId = _manager.GetValue<string>(row, "PanchayatId");

            IElection election = new Election();
            election.ElectionId = _manager.GetValue<int>(row, "ElectionId");

            IVoter voter = new Voter();
            voter.VoterId = _manager.GetValue<string>(row, "VoterId");
            voter.Name = _manager.GetValue<string>(row, "Name");


            IConstituency constituency = new Constituency();
            constituency.District = district;
            constituency.Panchayat = panchayat;
            constituency.Ward = ward;
            constituency.Election = election;
            
            obj.Constituency = constituency;
            obj.Voter = voter;

            obj.Party = _manager.GetValue<string>(row, "Party");
            obj.Symbol = _manager.GetValue<string>(row, "Symbol");
            obj.VotesEncrypted = _manager.GetValue<string>(row, "NoOfVotes");


        }


        #region IDalCandidate Members

        public ICandidate GetCandidate(string voterId, IConstituency constituency)
        {
            throw new NotImplementedException();
        }

        public IList<ICandidate> SearchCandidates(ICandidateSearchCriteria candidateSearchCriteria)
        {
            _manager.StoredProcedureName = SP_SEARCH_CANDIDATES;
            _manager.AddInParameter("@DistrictId", DbType.String, candidateSearchCriteria.Constituency.District.DistrictId);
            _manager.AddInParameter("@PanchayatId", DbType.String, candidateSearchCriteria.Constituency.Panchayat.PanchayatId);
            _manager.AddInParameter("@WardId", DbType.String, candidateSearchCriteria.Constituency.Ward.WardId);
            _manager.AddInParameter("@ElectionID", DbType.Int32, candidateSearchCriteria.Constituency.Election.ElectionId);
            _manager.AddInParameter("@Name", DbType.String, candidateSearchCriteria.Voter.Name);
            _manager.AddInParameter("@VoterId", DbType.String, candidateSearchCriteria.Voter.VoterId);

            _manager.AddInParameter("@Party", DbType.String, candidateSearchCriteria.Party);

            IList<ICandidate> listCandidates = new List<ICandidate>();
            foreach (ICandidate candidate in ConvertAll(_manager.ExecuteDataSet()))
                listCandidates.Add(candidate);

            return listCandidates;
        }

        public bool AddCandidate(ICandidate candidate)
        {
            _manager.StoredProcedureName = SP_INSERT_CANDIDATE;

            _manager.AddInParameter("@DistrictId", DbType.String, candidate.Constituency.District.DistrictId);
            _manager.AddInParameter("@PanchayatId", DbType.String, candidate.Constituency.Panchayat.PanchayatId);
            _manager.AddInParameter("@WardId", DbType.String, candidate.Constituency.Ward.WardId);
            _manager.AddInParameter("@VoterId", DbType.String, candidate.Voter.VoterId);
            _manager.AddInParameter("@ElectionId", DbType.Int32, candidate.Constituency.Election.ElectionId);
            _manager.AddInParameter("@Party", DbType.String, candidate.Party);
            _manager.AddInParameter("@Symbol", DbType.String, candidate.Symbol);




            // _manager.AddParameter("@binaryValue", SqlDbType.VarBinary, voter.Photo.Length).Value = voter.Photo;
            // _manager.AddInParameter("@Photo", DbType.B , voter.Photo);


            _manager.ExecuteNonQuery();

            return true;
        }

        public bool UpdateVote(ICandidate candidate, IVoter voter)
        {
            _manager.StoredProcedureName = SP_ADD_VOTE;

            _manager.AddInParameter("@CandidateId", DbType.String, candidate.CandidateId);
            _manager.AddInParameter("@VoterId", DbType.String, voter.VoterId);
            _manager.AddInParameter("@ElectionId", DbType.Int32, candidate.Constituency.Election.ElectionId);

            _manager.AddInParameter("@Votes", DbType.String, candidate.VotesEncrypted);


            _manager.ExecuteNonQuery();

            return true;
        }

        public ICandidate GetVote(ICandidate candidate)
        {
            _manager.StoredProcedureName = SP_GET_VOTE;
            _manager.AddInParameter("@CandidateId", DbType.String, candidate.CandidateId);
            ICandidate _candidate = Convert(_manager.ExecuteDataSet());
            return _candidate;
        }

        public bool UpdateCandidate(ICandidate candidate)
        {
            _manager.StoredProcedureName = SP_UPDATE_CANDIDATE;

            _manager.AddInParameter("@CandidateId", DbType.String, candidate.CandidateId);
            _manager.AddInParameter("@DistrictId", DbType.String, candidate.Constituency.District.DistrictId);
            _manager.AddInParameter("@PanchayatId", DbType.String, candidate.Constituency.Panchayat.PanchayatId);
            _manager.AddInParameter("@WardId", DbType.String, candidate.Constituency.Ward.WardId);
            _manager.AddInParameter("@VoterId", DbType.String, candidate.Voter.VoterId);
            _manager.AddInParameter("@ElectionId", DbType.Int32, candidate.Constituency.Election.ElectionId);
            _manager.AddInParameter("@Party", DbType.String, candidate.Party);
            _manager.AddInParameter("@Symbol", DbType.String, candidate.Symbol);


            _manager.ExecuteNonQuery();

            return true;
        }

        #endregion

        #region IDalCandidate Members


        public ICandidate GetCandidate(int candidateId)
        {
            _manager.StoredProcedureName = SP_GET_CANDIDATE;
            _manager.AddInParameter("@CandidateId", DbType.String, candidateId);
            ICandidate candidate = Convert(_manager.ExecuteDataSet());
            return candidate;
        }

        #endregion

        #region IDalCandidate Members


        public List<ICandidate> GetCandidates(IConstituency constituency)
        {
            _manager.StoredProcedureName = SP_SEARCH_CANDIDATES_CONSTITUENCY;
            _manager.AddInParameter("@DistrictId", DbType.String, constituency.District.DistrictId);
            _manager.AddInParameter("@PanchayatId", DbType.String, constituency.Panchayat.PanchayatId);
            _manager.AddInParameter("@WardId", DbType.String, constituency.Ward.WardId);
            _manager.AddInParameter("@ElectionID", DbType.Int32, constituency.Election.ElectionId);

            List<ICandidate> listCandidates = new List<ICandidate>();
            foreach (ICandidate candidate in ConvertAll(_manager.ExecuteDataSet()))
                listCandidates.Add(candidate);

            return listCandidates;
        }

        #endregion

        #region IDalCandidate Members


        public bool AddVote(ICandidate candidate)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
